package pers.zc.activiti.scheduling;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

/**
 * @description 定时任务调度
 * @Author Lin FuYuan
 * @date 2020/4/2
 */
@Component
public class SchedulingService {
    @Autowired
    private ThreadPoolTaskScheduler taskScheduler ;
    private static ConcurrentHashMap<String ,ScheduledFuture>  futureMap = new ConcurrentHashMap<>(16);
    /**
     * @param
     * @return java.lang.Boolean
     * @author Lin FuYuan
     * @date 2020/3/10
     */
    public Boolean startTask(String key) {

        /**
         * ThreadPoolTaskScheduler：线程池任务调度类，能够开启线程池进行任务调度。
         * ThreadPoolTaskScheduler.schedule()方法会创建一个定时计划ScheduledFuture，在这个方法需要添加两个参数，
         * Runnable（线程接口类） 和CronTrigger（定时任务触发器）
         * YouXinConfiguration：自定义读取yml文件中数据的类，通过该类读取yml文件中cron时间表达式，从而可以达到定时时间可配置的效果。
         * MyRunnable1与MyRunnable2类：这两个类都是实现了Runnable接口，重写了run方法，定时任务的逻辑代码就是在其中实现。
         */
        if(futureMap.get(key)!=null){
            boolean cancelled = futureMap.get(key).isCancelled();
            if(cancelled){
                futureMap.get(key);
            }else{
                return true;
            }
        }
        try {

            TaskEntity e= new TaskEntity();
            e.setCorn("0/5 * * * * ?");
            e.setName(key);
            ScheduledFuture scheduledFuture = taskScheduler.schedule(new SchduleTask(e), new CronTrigger(e.getCorn()));
            futureMap.put(key,scheduledFuture);
            scheduledFuture = taskScheduler.schedule(new SchduleTask(e), new CronTrigger(e.getCorn()));
            scheduledFuture.get();
        } catch (Exception e) {
            throw new RuntimeException("定时任务调度执行异常",e);
        }
        return true;
    }

    /**
     * 关闭定时任务调度
     *
     * @param
     * @return java.lang.Boolean
     * @author Lin FuYuan
     * @date 2020/3/10
     */
    public Boolean stopTask(String key) {
        if (futureMap.get(key) != null) {
            //true 等待任务执行完后关闭线程, false : 不等待  直接关闭线程
            Boolean cancel = futureMap.get(key).cancel(true);
            futureMap.remove(key);
            return cancel;
        }
        return true;
    }

    private static class SchduleTask implements Runnable {
        private TaskEntity entityTask;
        public SchduleTask(TaskEntity entity){
            this.entityTask = entity;
        }
        @Override
        public void run(){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("定时调度运行" + Thread.currentThread().getName() + ":" + sdf.format(new Date())+":"+ entityTask.getCorn()+":"+entityTask.getName());
        }

        public TaskEntity getEntity(){
            return this.entityTask;
        }
    }


}
